package com.nulldev.util.data.DataTransferAPI;

import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;

import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.networking.rudp.util.SerializationUtils;

public class DataTransferWriter implements Closeable, Flushable {

	private final OutputStream os;

	public DataTransferWriter(final OutputStream os) {
		this.os = os;
	}

	public void writeInt(final int value) throws IOException {
		byte[] buffer = new byte[4];
		MathUtil.putInt(value, buffer, 0);
		this.os.write(buffer);
	}

	public void writeLong(final long value) throws IOException {
		byte[] buffer = new byte[8];
		MathUtil.putLong(value, buffer, 0);
		this.os.write(buffer);
	}

	public void writeBoolean(final boolean value) throws IOException {
		this.os.write(value ? 1 : 0);
	}

	public void write(final byte[] value) throws IOException {
		if (value == null || value.length == 0) {
			throw new NullPointerException("write(byte[]): value == null or empty!");
		}
		this.os.write(value);
	}

	public void write(final String value) throws IOException {
		if (value == null || value.isEmpty()) {
			throw new NullPointerException("write(String): value == null or empty!");
		}
		final byte[] d = value.getBytes();
		this.writeInt(d.length);
		this.write(d);
	}

	public void write(final Serializable value) throws IOException {
		if (value == null) {
			throw new NullPointerException("write(Serializable): value == null!");
		}
		final byte[] s = SerializationUtils.getInstance().serialize(value);
		this.writeInt(s.length);
		this.write(s);
	}

	@Override
	public void flush() throws IOException {
		this.os.flush();
	}

	public void close() throws IOException {
		this.os.close();
	}
}
